package com.example.service;

import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
import com.example.dao.ColumnsDao;
import com.example.dao.TablesDao;
import com.example.dto.req.ExcelReq;
import com.example.dto.req.WordReq;
import com.example.output.ExcelInfo;
import com.example.output.WordDesc;
import com.example.output.WordField;
import com.example.output.WordInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ExcelServiceImpl implements ExcelService {
    
    @Autowired
    private TablesDao tablesDao;
    @Autowired
    private ColumnsDao columnsDao;
    
    @Override
    public void excelTableName(ExcelReq req) {
        List<String> results = tablesDao.findByIdTableSchema(req.getBaseName())
                .stream().map(tables -> tables.getId().getTableName()).collect(Collectors.toList());
        
        // 向指定的文档中写入数据
        String path = req.getOutPutPath();
        ExcelWriter writer;
        if (req.getSheetName() == null) {
            writer = ExcelUtil.getWriter(path);
        } else {
            writer = ExcelUtil.getWriter(path, req.getSheetName());
        }
        
        // 一次性写出内容，使用默认样式，强制输出标题
        writer.write(results, true);
        // 关闭writer，释放内存
        writer.close();
    }
    
    @Override
    public void excel(ExcelReq req) {
        // 基于COLUMNS表的TABLE_SCHEMA字段查询所有记录，并构造写入文档的数据结构
        List<ExcelInfo> results = columnsDao.findByIdTableSchema(req.getBaseName())
                .stream().map(ExcelInfo::toDto).collect(Collectors.toList());
        
        // 向指定的文档中写入数据
        String path = req.getOutPutPath();
        ExcelWriter writer;
        if (req.getSheetName() == null) {
            writer = ExcelUtil.getWriter(path);
        } else {
            writer = ExcelUtil.getWriter(path, req.getSheetName());
        }
        
        // 一次性写出内容，使用默认样式，强制输出标题
        writer.write(results, true);
        // 关闭writer，释放内存
        writer.close();
    }
    
    @Override
    public void word(WordReq req) {
        // 基于COLUMNS表的TABLE_SCHEMA字段查询所有记录，并构造写入文档的数据结构
        List<WordInfo> wordInfos = new ArrayList<>();
        columnsDao.findByIdTableSchema(req.getBaseName()).forEach(columns -> {
            WordInfo wordRes = wordInfos.stream()
                    .filter(data -> data.getTableName().equals(columns.getId().getTableName()))
                    .findFirst()
                    .orElse(null);
            if (wordRes == null) {
                wordRes = new WordInfo();
                wordInfos.add(wordRes);
            }
            
            wordRes.setTableName(columns.getId().getTableName());
            
            int startIndex = columns.getColumnComment().indexOf("。");
            if (startIndex == -1) {
                wordRes.getColumns().add(WordField.toDto(columns));
                return;
            }
            
            String title = columns.getColumnComment().substring(0, startIndex).trim();
            String content = columns.getColumnComment().substring(startIndex + 1)
                    .replaceAll("\\s*;\\s*", "\n")
                    .replaceAll("\\s*；\\s*", "\n")
                    .replaceAll("\\s*:\\s*", "")
                    .replaceAll("\\s*：\\s*", "");
            wordRes.getDesc().add(WordDesc.toDto(title, content));
            
            columns.setColumnComment("见详细描述" + wordRes.getDesc().size());
            wordRes.getColumns().add(WordField.toDto(columns));
        });
        HashMap<String, Object> table = new HashMap<String, Object>() {{
            put("table", wordInfos);
        }};
        
        // 配置循环结构
        LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
        Configure config = Configure.builder().useSpringEL().bind("columns", policy).build();
        
        // 向指定的文档中写入数据
        try {
            XWPFTemplate template = XWPFTemplate.compile(req.getTemplatePath(), config).render(table);
            template.writeAndClose(new FileOutputStream(req.getOutPutPath()));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
